﻿/*
* Copyright (C) Microsoft. All rights reserved.  
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not 
* use this file except in compliance with the License.  You may obtain a copy 
* of the License at http://www.apache.org/licenses/LICENSE-2.0  
* 
* THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
* WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
* MERCHANTABLITY OR NON-INFRINGEMENT. 
*
* See the Apache License, Version 2.0 for specific language governing 
* permissions and limitations under the License.
*
*/
//
// page.xaml.h
// Declaration of the page class
//

#pragma once

#include "app\page.g.h"
#include <journal/views/interfaces.h>

namespace journal
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public ref class page sealed
    {
    public:
        page();

    internal:
        Windows::UI::Xaml::Controls::Canvas^ TopCanvas() { return _TopCanvas; }
        Windows::UI::Xaml::Controls::AppBar^ AppBar() { return _AppBar; }

    internal:
        class settings_observer : public isettings_service_observer, public std::enable_shared_from_this<settings_observer>
        {
        public:
            settings_observer(page^ p) : _p(p) {} 

            void onBeforeSettingChange(const b::wchar* fullName) {}
            void onAfterSettingChange(const b::wchar* fullName)
            {
                if (std::wstring(fullName).compare(constants::general::name::zoomLevel) == 0)
                {
                    _p->updateZoomIcon();
                    _p->updateColorIcon();
                    _p->updateThicknessIcon();
                    _p->updateToolIcon();
                    _p->updateCameraIcon();

                    // enable/disable appbar buttons depending on the view
                    bool enabled = !(constants::general::zoomLevel() == view::layout_id::grid);
                }
                else if (std::wstring(fullName).compare(constants::general::name::stackState) == 0)
                {
                    _p->updateZoomIcon();
                }
                else if (std::wstring(fullName).compare(constants::ink::name::inkColor) == 0)
                {
                    _p->updateColorIcon();
                }
                else if (std::wstring(fullName).compare(constants::ink::name::inkTool) == 0)
                {
                    _p->updateToolIcon();
                }
                else if (std::wstring(fullName).compare(constants::ink::name::baseWidth) == 0)
                {
                    _p->updateThicknessIcon();
                }
                else if (std::wstring(fullName).compare(constants::general::name::paperType) == 0)
                {
                    _p->updatePaperTypeIcon();
                }
                else if (std::wstring(fullName).compare(constants::ink::name::touchInputMode) == 0)
                {
                    _p->updateTouchInputModeIcon();
                }
                else if (std::wstring(fullName).compare(constants::general::name::backgroundPackedColor) == 0)
                {
                    // update settings textbox if needed
                    _p->updateBackgroundColorSetting();
                }
            }

            page^ _p;
        };

        class ui_service : public a::iui_service
        {
        public:
            ui_service(page^ p) : _p(p) {}

            // iui_service
            void showAppBar(const a::app_bar_id id)
            {
                _p->showAppBar(id);
            }

            void hideAppBar()
            {
                _p->hideAppBar();
            }

            void enableAppBar(const bool enabled)
            {
                _p->enableAppBar(enabled);
            }

            void enableAppBarButton(const a::app_bar_button_id id, const bool enabled)
            {
                _p->enableAppBarButton(id, enabled);
            }

            void raiseAppBarVisibilityChange(const bool visible)
            {
                _observerSource.raise([=](const std::shared_ptr<a::iui_service_observer>& observer, void* context)
                {
                    observer->onAppBarVisibilityChange(visible);
                });
            }

            void setText(const b::wchar* text, const int line = 0)
            {
                String^ t =  ref new String(text);
                _p->Line1Text->Text = t;
                _p->Line1ShadowText->Text = t;
            }

            void setTextVisibility(const bool visible)
            {
                if (visible)
                {
                    _p->Line1Grid->Visibility = Windows::UI::Xaml::Visibility::Visible;
                    _p->Line1ShadowGrid->Visibility = Windows::UI::Xaml::Visibility::Visible;
                }
                else
                {
                    _p->Line1Grid->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
                    _p->Line1ShadowGrid->Visibility = Windows::UI::Xaml::Visibility::Collapsed;
                }
            }

            void refreshAppBar()
            {
                _p->refreshAppBar();
            }

            void showDialog(const b::wchar* text)
            {
                _p->showDialog(text);
            }

            b::int32 addObserver(const std::shared_ptr<a::iui_service_observer>& observer)
            {
                return _observerSource += observer;
            }

            void removeObserver(const std::shared_ptr<a::iui_service_observer>& observer)
            {
                _observerSource -= observer;
            }

            void removeObserver(const b::int32 cookie)
            {
                _observerSource -= cookie;
            }

            // returns whether any of the flyouts are open
            bool isActive()
            {
                return 
                    _p->SettingsColorFlyout->IsOpen ||
                    _p->ZoomFlyout->IsOpen ||
                    _p->PenTypeFlyout->IsOpen ||
                    _p->_ColorFlyout->IsOpen ||
                    _p->CameraFlyout->IsOpen ||
                    _p->_PenFlyout->IsOpen ||
                    _p->PaperTypeFlyout->IsOpen;
            }

            page^ _p;
            b::observable_source<a::iui_service_observer> _observerSource;
        };

        void setCommandObserver(const std::shared_ptr<view::icommand_observer>& observer)
        {
            _commandObserver = observer;
        }

        std::shared_ptr<a::iui_service> uiService() { return _uiService; }

        void onLaunched();

        virtual void OnNavigatedTo(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e);
        void onAppBarOpened(Platform::Object^ sender, Platform::Object^ args);
        void onAppBarClosed(Platform::Object^ sender, Platform::Object^ args);
        void clickCopy();
        void clickPaste();
        void clickAdd();
        void clickUndo();
        void clickRedo();

        // Touch mode
        void clickTouchInputModeOn();
        void clickTouchInputModeOff();

        // Zoom level
        void clickZoomLevel();
        void clickZoomGrid();
        void clickZoomFullPage();
        void clickZoomFitToWidth();
        void clickZoomExpandStack();

        // Pen type
        void clickPenType();
        void clickBallpointPen();
        void clickEraser();
        void clickSelectionTool();

        // Pens
        void clickPen();
        void clickPen1();
        void clickPen2();
        void clickPen3();
        void clickPen4();
        void clickPen5();

        // Colors
        void clickColor();

        void clickBlackColor();
        void clickRedColor();
        void clickBlueColor();
        void clickYellowColor();
        void clickGreenColor();
        void clickPinkColor();

        // Camera
        void clickCamera();
        void clickFileSystemPhoto();
        void clickCameraPhoto();

        // Paper type
        void clickPaperType();

        void clickPaper0();
        void clickPaper1();
        void clickPaper2();
        void clickPaper3();
        void clickPaper4();

        // Photo app bar
        void clickDeletePhoto();
        void clickAlignPhoto();
        void clickBringToFrontPhoto();
        void clickOKPhoto();
        void clickCancelPhoto();

        // Grid app bar
        void clickDeletePage();
        void clickOKPage();

        // Lasso app bar
        void clickCopySelection();
        void clickOKSelection();

        // Other
        void updateSettingsColor();
        void settingsInputModeChecked();

        void onCommandsRequested(
            Windows::UI::ApplicationSettings::SettingsPane^ settingsPane, 
            Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs^ eventArgs
            );
        
        void onSettingsCommand(Windows::UI::Popups::IUICommand^ command);

    private:
        void finishClick();
        void showDialog(const wchar_t* message);
        void nyi();
        void updateColorIcon();
        void updateThicknessIcon();
        void updateToolIcon();
        void updateZoomIcon();
        void updateCameraIcon();
        void updateTouchInputModeIcon();
        void updatePaperTypeIcon();
        void updateBackgroundColorSetting();
        void showAppBar(const a::app_bar_id id);
        void hideAppBar();
        void enableAppBar(const bool enabled);
        void enableAppBarButton(const a::app_bar_button_id id, const bool enabled); 
        void hideFlyouts();
        void onZoomLevelChanged();
        void onStackStateChanged();
        void refreshAppBar();

        std::shared_ptr<view::icommand_observer> _commandObserver;
        std::shared_ptr<a::iui_service> _uiService;
        std::shared_ptr<isettings_service_observer> _settingsObserver;

        Windows::Foundation::EventRegistrationToken _settingsToken;

    };
}
